import './../topic-sider-bar/sider-modal/DeviceNodeManagePopUp.scss'
import { ChangeEvent, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"
import {
    Modal, Input, Space, Form, Select,
    Row,
    Col,
    Tabs,
    Upload,
    UploadProps,
    Button,
    Divider,
    Tree,
    Checkbox,
    Empty,
    Tooltip
} from "antd";
import LoadingWapper from "../../../components/loading/LoadingWapper";
import systemApi from "../../../api/system";
import { DocConfig, DocInstance, TopicNodeActionType, TopicType } from "../../../utils/types";
import {
    addTreePropertyForList, commonErrorMsg, commonSuccessMsg,
    deepCloneV2, dfsRecursive, dfsRecursiveFromInner, filterTree,
    findHalfCheckedKeys, generateTreeData, getChangeEventValue,
    getCheckBoxChangeEventValue, getNodeChildDeviceNodeCheckedCount, getNodeChildDeviceNodeCount, handleJumpEditPage, insertChildNodeListToTree, insertPeerNodeListToTree, insertTopPeerNodeListToTree, isEmpty,
    makeClassNameList,
    swapListElements, toastShort, tree2List
} from "../../../utils";
import { CheckOutlined, DownOutlined, ExclamationCircleOutlined, ExpandAltOutlined, LeftCircleOutlined, PartitionOutlined, PlusCircleOutlined, PlusCircleTwoTone, QuestionCircleOutlined, RedoOutlined, RightCircleOutlined, UndoOutlined, VerticalAlignMiddleOutlined } from '@ant-design/icons';
import { generateDocInstance, processDocInstanceBeforeUpdate } from '../word-editor/editor-doc-item-generate';
import { useLocation } from 'react-router-dom';
import TopicTreeContextMenu from '../../../components/context-menu/TopicTreeContextMenu';
import comDocContext from '../../../context/DocContext';
import { throttle } from 'lodash';
import { CheckboxChangeEvent } from 'antd/es/checkbox';
import AddTopicMoal from '../topic-sider-bar/sider-modal/AddTopicMoal';
import ReNameTopicModal from '../topic-sider-bar/sider-modal/ReNameTopicModal';
import useStateDebounce from '../../../hooks/useStateDebounce';

interface Props {
}

const {
    Search
} = Input;

const TopicManagePage = (props: Props) => {

    const {
        //规划数据实例
        comDocInstance,
        _setComDocInstance,
        //规划配置信息
        comDocConfig,
        currentFocusedDocItem,
        _setComFocusTopicNode,
    } = useContext(comDocContext);

    const contextMenuRef = useRef<any>(null);
    const pureTextTopicTreeRef = useRef<any>(null);
    const [windowFullHeight, setWindowFullHeight] = useState<number>(0);
    const [currentStep, setCurrentStep] = useState<'selectTitle' | 'selecteDevice'>('selectTitle');
    //所有规划大纲
    const [topicList, setTopicList] = useState<TopicType[]>([]);
    // //纯文本大纲
    // const [pureTextTopicList, setPureTextTopicList] = useState<TopicType[]>([]);

    const [draggingNodeKey, setDraggingNodeKey] = useState(null);

    const [pureTextTopicTreeHighLightNode, setPureTextTopicTreeHighLightNode] = useState<TopicType>(null);
    const [pureTextTopicTreeSelectedNode, setPureTextTopicTreeSelectedNode] = useState<TopicType>(null);

    const [pureTextTreeDataCheckedKeyList, setPureTextTreeDataCheckedKeyList] = useState<string[]>([]);
    //搜索
    const [pureTextTopicTreeDataSearchValue, setPureTextTopicTreeDataSearchValue] = useState("");
    const [pureTextTopicTreeExpandedKeys, setPureTextTopicTreeExpandedKeys] = useState<string[]>([]);

    const [deviceTopicSearchValue, setDeviceTopicSearchValue] = useState<string>('');

    const [deviceListSortType, setDeviceListSortType] = useState<string>('default');

    const [topicListHistoryList, setTopicListHistoryList] = useState(null);
    const [topicListHistoryIndex, setTopicHistoryIndex] = useState(0);

    const [delayUpdateComDocInstance, setDelayUpdateComDocInstance] = useState<DocInstance>(comDocInstance);

    const debouncedComDocInstance = useStateDebounce(delayUpdateComDocInstance, 100);

    useEffect(() => {
        _setComDocInstance({ ...debouncedComDocInstance })
    }, [debouncedComDocInstance])

    useEffect(() => {
        setWindowFullHeight(window.innerHeight);
    }, []);

    useEffect(() => {
        if (comDocInstance) {
            setTopicList(comDocInstance.topicList);
            const checkedPureTextTopicIdList = getInitPureTextTopicCheckedIdList(comDocInstance.topicList);
            // console.log("checkedPureTextTopicIdList--->", checkedPureTextTopicIdList)
            setPureTextTreeDataCheckedKeyList(checkedPureTextTopicIdList);
            // setPureTextTopicList(deepCloneV2(comDocInstance.topicList.filter(node => node.topicType == 'text')))
        }
    }, [comDocInstance])

    const getInitPureTextTopicCheckedIdList = (initTopicList: TopicType[]) => {
        let result = [];
        let _tree: TopicType[] = generateTreeData(addTreePropertyForList(initTopicList));
        dfsRecursive(_tree, (node: TopicType) => {
            if (node.topicType == 'text') {
                if (node.checked) {
                    result.push(node.id);
                } else if (node.children && node.children.filter(ele => ele.checked).filter(ele => ele.topicType === 'device').length) {
                    result.push(node.id);
                }
            }
        })
        return result;
    };

    const topicTree = useMemo(() => {
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                const childDeviceNodeCount = getNodeChildDeviceNodeCount(topic);
                const childDeviceNodeCheckedCount = getNodeChildDeviceNodeCheckedCount(topic);
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
                topic.childDeviceNodeCount = childDeviceNodeCount;
                topic.childDeviceNodeCheckedCount = childDeviceNodeCheckedCount;
            }
        })
        const topicTreeData: TopicType[] = deepCloneV2(_tree);
        return topicTreeData;
    }, [topicList])


    const pureTextTopicTreeData = useMemo(() => {
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                const childDeviceNodeCount = getNodeChildDeviceNodeCount(topic);
                const childDeviceNodeCheckedCount = getNodeChildDeviceNodeCheckedCount(topic);
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
                topic.childDeviceNodeCount = childDeviceNodeCount;
                topic.childDeviceNodeCheckedCount = childDeviceNodeCheckedCount;
            }
        })
        _tree = filterTree(_tree, (node) => node.topicType == 'text');
        const _pureTextTopicTreeData: TopicType[] = deepCloneV2(_tree);
        return _pureTextTopicTreeData;
    }, [topicList]);

    const filteredForPureTextTopicTree = useMemo(() => {
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
            }
        })
        const _pureTextTopicTreeData: TopicType[] = deepCloneV2(_tree);
        return _pureTextTopicTreeData;
    }, [pureTextTopicTreeDataSearchValue, topicList]);

    const onNodeContextMenu = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, node: TopicType) => {
        if (!isEmpty(pureTextTopicTreeDataSearchValue)) {
            toastShort('warning', '请退出搜索模式后重试');
            return false;
        }
        e.preventDefault();
        e.stopPropagation();
        setPureTextTopicTreeHighLightNode(node)
        setPureTextTopicTreeSelectedNode(node);
        let originX = e.clientX;
        let originY = e.clientY;
        originY = originY - 42;
        if (originY + 268 > windowFullHeight) {
            originY = windowFullHeight - 350;
        }
        e.clientX = originX;
        e.clientY = originY;
        contextMenuRef.current.showContextMenu(e);
    }

    const onDoubleClickTextTopic = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, node: TopicType) => {
        e.preventDefault();
        e.stopPropagation();
        setPureTextTopicTreeHighLightNode(node)
        setPureTextTopicTreeSelectedNode(node);
        onPickerTreeNodeActionType('ReName', node)
    }

    const adaptNodeSerialNumber = (node: TopicType) => {
        if (node.topicType == 'device') {
            return null;
        }
        return (
            <div
                className='topic-tree-node-extra'
            >
                {node.serialNumber}&nbsp;
            </div>
        )
    }

    const formatSearchTextForAllTopicTree = (originStr: string) => {
        try {
            if (isEmpty(pureTextTopicTreeDataSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(pureTextTopicTreeDataSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{pureTextTopicTreeDataSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{pureTextTopicTreeDataSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const renderPureTextTopicTreeNode = (node: TopicType) => {
        const isDragging = node.key === draggingNodeKey;
        const className = isDragging ? 'draggingNode' : '';
        return (
            <div
                className={makeClassNameList(['device-manage-tree-node', className])}
                //@ts-ignore
                topic-type={node.topicType}
                key={node.id}
                onContextMenu={(e) => onNodeContextMenu(e, node)}
                onDoubleClick={(e) => onDoubleClickTextTopic(e, node)}
                style={pureTextTopicTreeHighLightNode && pureTextTopicTreeHighLightNode.id == node.id ? { backgroundColor: '#f2f2f2' } : null}
            >
                <div
                    className='flex-row device-manage-tree-node-content'
                    style={pureTextTopicTreeHighLightNode && pureTextTopicTreeHighLightNode.id == node.id ? { borderBottom: '1px solid #7f7f7f' } : null}
                >
                    {adaptNodeSerialNumber(node)}
                    <div className='single-line-text' style={{ maxWidth: 280, fontWeight: node.topicType == 'text' ? 'normal' : 'bold' }}>
                        {formatSearchTextForAllTopicTree(node.title)}
                    </div>
                    {
                        node.topicType == 'text' && node.childDeviceNodeCount && node.childDeviceNodeCount != node.directDeviceChildNodeCount ?
                            <Tooltip
                                title={"本节包含项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-total-count'>{node.childDeviceNodeCount}</div>
                            </Tooltip>
                            :
                            null
                    }
                    {
                        node.topicType == 'text' && node.childDeviceNodeCheckedCount ?
                            <Tooltip
                                title={"本节选择项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-count'>{node.childDeviceNodeCheckedCount}</div>
                            </Tooltip>
                            :
                            null
                    }
                </div>
            </div>
        );
    };

    const onSelectPureTextTopicNode = (ids: string[]) => {
        const findTopicNode = topicList.find(ele => {
            return ele.id == ids[0];
        })
        setPureTextTopicTreeSelectedNode(findTopicNode);
        setPureTextTopicTreeHighLightNode(findTopicNode);
    };

    const onPureTextTreeDataCheckedChange = (checkedKeys: string[]) => {
        setPureTextTreeDataCheckedKeyList(checkedKeys);
    };

    const scrollTo = useCallback(
        throttle((target) => {
            const { bottom: currentBottom, top: currentTop } = target.getBoundingClientRect();
            const { bottom: boxBottom, top: boxTop } = document
                .getElementsByClassName('ant-tree-list-holder')[1]
                .getBoundingClientRect();
            if (currentTop > boxBottom - 48) {
                document.getElementsByClassName('ant-tree-list-holder')[1].scrollTop =
                    document.getElementsByClassName('ant-tree-list-holder')[1].scrollTop + 32;
            }
            if (boxTop + 48 > currentBottom) {
                document.getElementsByClassName('ant-tree-list-holder')[1].scrollTop =
                    document.getElementsByClassName('ant-tree-list-holder')[1].scrollTop - 32;
            }
        }, 100),
        [pureTextTopicTreeRef]
    );

    const onDragOver = (info: any) => {
        if (info.event.target) {
            scrollTo(info.event.target);
        }
    }

    const onDragStart = (info) => {
        setDraggingNodeKey(info.node.key);
    }

    const onDragEnd = (e) => {
        setDraggingNodeKey(null);
    }

    const findTreeNode = (treeData: TopicType[], targetNodeId: string): TopicType => {
        let findNode = null;
        treeData.forEach(node => {
            if (node.id == targetNodeId) {
                findNode = node;
            } else if (node.children && node.children.length && !findNode) {
                let _findNode = findTreeNode(node.children, targetNodeId);
                if (_findNode) {
                    findNode = _findNode;
                }
            }
        })
        return findNode;
    }

    const findNode = (key, data) => {
        let result;
        const find = (key, data) => {
            data.forEach(item => {
                if (item.key === key) {
                    result = item;
                } else if (item.children) {
                    find(key, item.children);
                }
            });
        };
        find(key, data);
        return result;
    };

    const deleteNode = (key, data) => {
        data.forEach((item, index, arr) => {
            if (item.key === key) {
                arr.splice(index, 1);
            } else if (item.children) {
                deleteNode(key, item.children);
            }
        });
    };

    const updateNodePid = (node: TopicType, pid: string): TopicType => {
        node.pid = pid;
        if (node.children) {
            node.children.forEach(child => updateNodePid(child, node.key));
        }
        return node;
    };

    // 获取兄弟节点和父节点的 key
    const getSiblingsAndParent = (key, data, parentKey = null) => {
        for (const item of data) {
            if (item.key === key) {
                return { siblings: data, parentKey };
            }
            if (item.children) {
                const result = getSiblingsAndParent(key, item.children, item.key);
                if (result) return result;
            }
        }
        return null;
    };

    function reorderParentArrayBasedOnSubset(parent, subset) {
        const parentMap = new Map(parent.map(e => [e.id, e]));
        // 更新父集中的元素属性
        subset.forEach(subElement => {
            if (parentMap.has(subElement.id)) {
                // 直接在映射中更新元素属性
                Object.assign(parentMap.get(subElement.id), subElement);
            }
        });

        // 创建一个排序后的父集数组
        const sortedAndUpdatedParent = parent
            .filter(e => parentMap.has(e.id)) // 保证只包括现在还存在的元素
            .sort((a, b) => {
                // 使用子集的顺序来排序父集中的元素
                const indexA = subset.findIndex(e => e.id === a.id);
                const indexB = subset.findIndex(e => e.id === b.id);
                return indexA - indexB;
            });

        // 返回更新和排序后的父集
        return sortedAndUpdatedParent;
    }

    const onTopicNodeDrop = (info) => {
        setDraggingNodeKey("");
        if (!isEmpty(pureTextTopicTreeDataSearchValue)) {
            toastShort('error', '搜索模式下不可使用拖拽功能');
            return;
        }
        const treeData = deepCloneV2(pureTextTopicTreeData);
        const dropKey = info.node.key;
        const dragKey = info.dragNode.key;
        const dropPos = info.node.pos.split('-');
        const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
        const targetNode = info.node;
        const dropNode = findNode(dropKey, treeData);
        const dragNode = findNode(dragKey, treeData);
        let newDragNode = dragNode;
        if (dropNode.topicType === 'device' && !info.dropToGap) {
            toastShort('error', '当前节点不可拖拽在所选位置')
            return;
        }
        deleteNode(dragKey, treeData);
        if (info.dropToGap) {
            const siblingsAndParent = getSiblingsAndParent(dropKey, treeData);
            if (!siblingsAndParent) return; // 确保找到了兄弟节点和父节点

            const siblings = siblingsAndParent.siblings;
            const parentKey = siblingsAndParent.parentKey;
            const index = siblings.findIndex(item => item.key === dropKey);
            if (dropPosition < 0) {
                siblings.splice(Math.max(0, index), 0, newDragNode); // 确保即使index为-1，也能正确处理
            } else {
                siblings.splice(index + 1, 0, newDragNode);
            }
            newDragNode = updateNodePid(newDragNode, parentKey);
        } else {
            if (dragNode && dragNode.pid == targetNode.id) {
                dfsRecursive(treeData, (node: TopicType) => {
                    if (node.id == targetNode.id) {
                        let findIndex = node.children.findIndex(topic => topic.id == dragNode.id);
                        let needToMoveDownNodeIndexList = [];
                        node.children.forEach((ele, index) => {
                            if (index <= findIndex) {
                                needToMoveDownNodeIndexList.push(index);
                            }
                        })
                        for (let i = needToMoveDownNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = needToMoveDownNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveDownNodeIndexList[i - 1];
                            node.children = swapListElements(node.children, currentNodeBeforeIndex, currentNodeIndex);
                        }
                    }
                })
            } else {
                const dropNode = findNode(dropKey, treeData);
                if (dropNode.topicType === 'device') {
                    return;
                }
                dropNode.children = dropNode.children || [];
                dropNode.children.unshift(dragNode);
                newDragNode = updateNodePid(dragNode, dropNode.id);
            }
        }
        //更新到数据
        if (isEmpty(newDragNode.pid)) {
            newDragNode.pid = '0';
        }
        const currentTreeDataTopicList: TopicType[] = [...tree2List(treeData)];
        currentTreeDataTopicList.forEach((ele, index) => {
            ele.index = index;
            if (newDragNode && ele.id == newDragNode.id) {
                ele = deepCloneV2(newDragNode)
            }
        })
        let newTopicList = reorderParentArrayBasedOnSubset(topicList, currentTreeDataTopicList);
        setTopicList(deepCloneV2(newTopicList));
    }

    const onPureTextTopicTreeDataSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        setPureTextTopicTreeDataSearchValue(getChangeEventValue(e));
    }


    const onpureTextTopicTreeExpanded = (keys: string[]) => {
        // console.log("keys", keys)
        setPureTextTopicTreeExpandedKeys(deepCloneV2(keys))
    }

    const expandAllNode = () => {
        let allKeys = [];
        dfsRecursive(pureTextTopicTreeData, (node: TopicType) => {
            allKeys.push(node.id)
        })
        setPureTextTopicTreeExpandedKeys(allKeys);
    };

    const unExpandAllNode = () => {
        setPureTextTopicTreeExpandedKeys([])
    }

    const deviceNodeList = useMemo(() => {
        let tempDeviceNodeList: TopicType[] = [];
        if (pureTextTopicTreeSelectedNode) {
            dfsRecursive(topicTree, (node: TopicType, level: number) => {
                if (node.id == pureTextTopicTreeSelectedNode.id) {
                    dfsRecursive(node.children, (subNode: TopicType) => {
                        if (subNode.topicType == 'device') {
                            let findTextNode = topicList.find(textTopic => textTopic.id == subNode.pid);
                            if (findTextNode) {
                                subNode.parentTextTopicTitle = findTextNode.topicName;
                            }
                            tempDeviceNodeList.push(subNode);
                        }
                    })
                }

            })
        }
        return tempDeviceNodeList
            .filter(node => node.title.includes(deviceTopicSearchValue) || node.parentTextTopicTitle && node.parentTextTopicTitle.includes(deviceTopicSearchValue))
            .sort((a, b) => {
                if (deviceListSortType == 'default') {
                    return 0;
                }
                if (a.checked && !b.checked) {
                    return -1;
                }
                if (b.checked && !a.checked) {
                    return 1;
                }
                return 0;
            });
    }, [topicList, pureTextTopicTreeSelectedNode, deviceTopicSearchValue, deviceListSortType]);

    const onDeviceTopicSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        setDeviceTopicSearchValue(getChangeEventValue(e));
    }

    const checkDeviceNodeIsChecked = (node: TopicType) => {
        return node.checked;
    };

    const checkDeviceNodeIsDisable = (node: TopicType) => {
        return false;
        if (node.pid !== pureTextTopicTreeSelectedNode.id && node.checked) {
            return true;
        } else {
            return false
        }
    }

    const onCheckedChange = (e: CheckboxChangeEvent, node: TopicType) => {
        const checked = getCheckBoxChangeEventValue(e);
        let tempTopicList = topicList;
        tempTopicList.forEach(deviceNode => {
            if (deviceNode.id == node.id) {
                deviceNode.checked = checked;
            }
        })
        setTopicList([...tempTopicList]);
    }

    const formatDeviceTopicSearchText = (originStr: string) => {
        try {
            if (isEmpty(deviceTopicSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(deviceTopicSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{deviceTopicSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{deviceTopicSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const onDeviceListSortTypeChange = (value: string) => {
        setDeviceListSortType(value)
    }

    function findPathInForest(forest, targetId) {
        // 遍历每一个根节点
        for (let root of forest) {
            // 调用递归函数搜索路径
            const path = findPath(root, targetId);
            // 如果找到路径（非空数组），返回这个路径
            if (path.length) {
                return path;
            }
        }
        // 如果所有根节点都没有找到路径，返回空数组
        return [];
    }

    function findPath(root, targetId) {
        if (root.id === targetId) {
            return [root.id];
        }
        if (root.children) {
            for (let child of root.children) {
                const path = findPath(child, targetId);
                if (path.length) {
                    return [root.id, ...path];
                }
            }
        }
        return [];
    }

    const clickDeviceNode = (node: TopicType) => {
        const parentTextTopic = topicList.find(ele => ele.id == node.pid)
        if (parentTextTopic) {
            const pathIdList = findPathInForest(pureTextTopicTreeData, node.pid);
            let _pureTextTopicTreeExpandedKeys = [...pureTextTopicTreeExpandedKeys];
            pathIdList.forEach(id => {
                if (!_pureTextTopicTreeExpandedKeys.includes(id)) {
                    _pureTextTopicTreeExpandedKeys.push(id)
                }
            })
            setPureTextTopicTreeHighLightNode(parentTextTopic);
            setPureTextTopicTreeExpandedKeys([..._pureTextTopicTreeExpandedKeys])
            pureTextTopicTreeRef.current.scrollTo({ key: node.pid });
            setTimeout(() => {
                pureTextTopicTreeRef.current.scrollTo({ key: node.pid })
            }, 50);
        }
    }

    /************ 规划大纲的操作树相关逻辑 start ************/

    const addTopicModalRef = useRef<any>(null);

    const renameTopicModalRef = useRef<any>(null);

    const [currentTreeNodeActionType, setCurrentTreeNodeActionType] = useState<TopicNodeActionType>(null);

    const onContextMenuClose = () => {
        setPureTextTopicTreeHighLightNode(null);
    }

    const moveNode = (nodeList: TopicType[], targetId: string, direction: 'up' | 'down' | 'top' | 'bottom'): TopicType[] => {
        let findIndex = -1;
        if (nodeList.length == 0 || nodeList.length == 1) {
            return nodeList;
        }
        for (let i = 0; i < nodeList.length; i++) {
            if (nodeList[i].id == targetId) {
                findIndex = i;
                break;
            }
        }
        if (findIndex > -1) {
            const targetNodePid = nodeList[findIndex].pid;
            switch (direction) {
                case 'top':
                    let needToMoveDownNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i <= findIndex) {
                                needToMoveDownNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveDownNodeIndexList[0] == findIndex) {
                        toastShort('warning', '该节点已置顶，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = needToMoveDownNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = needToMoveDownNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveDownNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'bottom':
                    let needToMoveUpNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i >= findIndex) {
                                needToMoveUpNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveUpNodeIndexList[needToMoveUpNodeIndexList.length - 1] == findIndex) {
                        toastShort('warning', '该节点已置底，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = 0; i < needToMoveUpNodeIndexList.length; i++) {
                            const currentNodeIndex = needToMoveUpNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveUpNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'up':
                    if (
                        nodeList[findIndex - 1] &&
                        nodeList[findIndex - 1].pid == targetNodePid
                    ) {
                        let currentChildrenNodeIndexList: number[] = [];
                        for (let i = 0; i < nodeList.length; i++) {
                            if (nodeList[i].pid == targetNodePid) {
                                if (i <= findIndex) {
                                    currentChildrenNodeIndexList.push(i)
                                }
                            }
                        }
                        let _nodeList = nodeList;
                        _nodeList = swapListElements(_nodeList, currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 2], currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 1]);
                        toastShort('success', commonSuccessMsg)
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置顶，不可继续上移')
                    }
                    break;
                case 'down':
                    if (nodeList[findIndex + 1] && nodeList[findIndex + 1].pid == targetNodePid) {
                        toastShort('success', commonSuccessMsg)
                        const _nodeList = swapListElements(nodeList, findIndex, findIndex + 1);
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置底，不可继续下移')
                    }
                    break;
                default:
                    break;
            }
            return nodeList;
        } else {
            toastShort('error', '节点不存在，请您刷新页面重试！')
        }
    }

    const handleMoveCurrentSelectedNode = (moveType: 'up' | 'down' | 'top' | 'bottom') => {
        try {
            let _tempTopicList = topicList;
            _tempTopicList = moveNode(_tempTopicList, pureTextTopicTreeSelectedNode.id, moveType);
            _tempTopicList = deepCloneV2(_tempTopicList);
            setTopicList(_tempTopicList);
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const [modal, contextHolder] = Modal.useModal();

    const handleDeleteCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: `确认删除此${pureTextTopicTreeSelectedNode.topicType == 'device' ? '项目' : '大纲'}？`,
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToDeleteCurrentSelectedNode
        });
    }

    const confirmToDeleteCurrentSelectedNode = () => {
        try {
            let _tempTopicList = topicList;
            for (let i = 0; i < _tempTopicList.length; i++) {
                if (_tempTopicList[i].id == pureTextTopicTreeSelectedNode.id) {
                    _tempTopicList.splice(i, 1);
                    break;
                }
            }
            _tempTopicList = deepCloneV2(_tempTopicList);
            setTopicList(_tempTopicList);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const findAllDescendants = (treeData: TopicType[], nodeId: string) => {
        const result = [];
        function findDescendants(node) {
            if (!node || !node.children) return;
            node.children.forEach(child => {
                result.push(child.id);
                findDescendants(child);
            });
        }

        function findNodeAndDescendants(nodes) {
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].id === nodeId) {
                    findDescendants(nodes[i]);
                    break;
                }
                if (nodes[i].children) {
                    findNodeAndDescendants(nodes[i].children);
                }
            }
        }
        findNodeAndDescendants(treeData);
        return result;
    }

    const findTreePathByTargetNodeIdList = (treeData: TopicType[], nodeId: string) => {
        const map = new Map();
        // 建立每个节点与其父节点的映射
        function buildMap(node, parentId = null) {
            if (!node) return;
            map.set(node.id, parentId);
            if (node.children) {
                node.children.forEach(child => buildMap(child, node.id));
            }
        }
        // 遍历树数据，建立映射
        treeData.forEach(node => buildMap(node));
        // 从指定节点回溯到根节点
        const path = [];
        let currentId = nodeId;
        while (currentId !== null) {
            path.push(currentId);
            currentId = map.get(currentId);
        }
        return path.reverse(); // 反转数组，使其从根节点开始
    }


    const confirmToUnCheckedCurrentSelectedNode = () => {
        try {
            // //需要直接取消勾选的节点
            let needToUnCheckedIdList = findAllDescendants(topicTree, pureTextTopicTreeSelectedNode.id);
            // //需要取消勾选的节点(如果此节点是勾选的话);
            let needToUnCheckedIfNodeChecedIdList = findTreePathByTargetNodeIdList(topicTree, pureTextTopicTreeSelectedNode.id);
            const tempTopicTreeData = generateTreeData(topicList);
            dfsRecursive(tempTopicTreeData, (node: TopicType) => {
                if (node.id == pureTextTopicTreeSelectedNode.id) {
                    node.checked = false;
                }
                if (needToUnCheckedIdList.includes(node.id)) {
                    node.checked = false;
                }
                if (needToUnCheckedIfNodeChecedIdList.includes(node.id)) {
                    node.checked = false;
                }
            })
            setTopicList(deepCloneV2(tree2List(tempTopicTreeData)));
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }


    const handleUnCheckedCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: '确认从本文大纲中移除此节点吗？移除后您可在大纲配置中重新勾选',
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToUnCheckedCurrentSelectedNode,
        });
    }


    const onPickerTreeNodeActionType = (actionType: TopicNodeActionType, _pureTextTopicTreeSelectedNode?: TopicType) => {
        setCurrentTreeNodeActionType(actionType);
        switch (actionType) {
            case 'AddDeviceChildNode':
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextChildNode':
                if (Number(pureTextTopicTreeSelectedNode.topicLevel) >= 6) {
                    return toastShort('error', '大纲节点最多不能超过6级')
                }
                addTopicModalRef.current.openModal();
                break;
            case 'AddDevicePeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextPeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'MoveUp':
                handleMoveCurrentSelectedNode('up');
                break;
            case 'MoveDown':
                handleMoveCurrentSelectedNode('down');
                break;
            case 'MoveTop':
                handleMoveCurrentSelectedNode('top');
                break;
            case 'MoveBottom':
                handleMoveCurrentSelectedNode('bottom');
                break;
            case 'ReName':
                renameTopicModalRef.current.openModal(_pureTextTopicTreeSelectedNode ? _pureTextTopicTreeSelectedNode.topicName : pureTextTopicTreeSelectedNode.topicName);
                break;
            case 'Delete':
                handleDeleteCurrentSelectedNode();
                break;
            case 'UnChecked':
                handleUnCheckedCurrentSelectedNode();
                break;
            default:
                break;
        }
    }

    const onChangeTopic = (newTopic: TopicType, originTopic: TopicType) => {
        try {
            let _tempTreeData = topicTree;
            let _checkedTopicIdList = pureTextTreeDataCheckedKeyList;
            if (originTopic) {
                deleteNode(originTopic.id, _tempTreeData)
            }
            newTopic.checked = true;
            newTopic.childrenDeviceTopicListLength = 0;
            _checkedTopicIdList.push(newTopic.id);
            setPureTextTreeDataCheckedKeyList([..._checkedTopicIdList]);
            let newTopicNodeList = [newTopic];
            switch (currentTreeNodeActionType) {
                case 'AddDeviceChildNode':
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    break;
                case 'AddTextChildNode':
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    break;
                case 'AddDevicePeerNode':
                    if (pureTextTopicTreeSelectedNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    }
                    break;
                case 'AddTextPeerNode':
                    if (pureTextTopicTreeSelectedNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, pureTextTopicTreeSelectedNode.id)
                    }
                    break;
                default:
                    break;
            }
            const _tempTopicList = [...tree2List(_tempTreeData)];
            setTopicList(_tempTopicList);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }


    const _onReNameFinish = (newName: string) => {
        let _tempTopicList = topicList;
        _tempTopicList.forEach(topic => {
            if (topic.id == pureTextTopicTreeSelectedNode.id) {
                topic.topicName = newName;
            }
        })
        _tempTopicList = deepCloneV2(_tempTopicList);
        setTopicList(_tempTopicList)
    }

    /************ 规划大纲的操作树相关逻辑 end *************/

    const resetTopicListCheckedStatus = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: `确认恢复大纲与规划项目为系统默认推荐？`,
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToResetTopicListCheckedStatus
        });
    };

    const confirmToResetTopicListCheckedStatus = () => {

    }

    const checkIsSelectedAllDeviceToicList = (): boolean => {
        let isSelectedAll = true;
        if (deviceNodeList.length == 0) {
            isSelectedAll = false;
        }
        deviceNodeList.forEach(node => {
            if (!checkDeviceNodeIsChecked(node)) {
                isSelectedAll = false;
            }
        })
        return isSelectedAll;
    }

    const switchCheckAllStatus = () => {
        const isCheckedAll = checkIsSelectedAllDeviceToicList();
        let desc = isCheckedAll ? "确认将面板内规划项目全部取消勾选？" : "确认全部勾选面板内规划项目";
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: desc,
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToSwitchCheckedAllStatus
        });
    };

    const confirmToSwitchCheckedAllStatus = () => {
        const isCheckedAll = checkIsSelectedAllDeviceToicList();
        const checked = !isCheckedAll;
        let tempTopicList = topicList;
        deviceNodeList.forEach(node => {
            const deviceNode = tempTopicList.find(ele => ele.id == node.id);
            deviceNode.checked = checked;
        })
        setTopicList([...tempTopicList]);
    };

    const handleOpenAddDeviceTopicModal = () => {
        onPickerTreeNodeActionType('AddDeviceChildNode');
    }


    const confirmToUpdateTopicList = () => {
        let tempTopicList = topicList;
        tempTopicList.forEach(node => {
            if (pureTextTreeDataCheckedKeyList.includes(node.id)) {
                node.checked = true;
            }
        })
        let newTopicTree = generateTreeData(tempTopicList);
        dfsRecursive(newTopicTree, (node: TopicType) => {
            if (node.topicType == 'text') {
                let childDeviceTopicTotalCount = 0;
                let childDeviceTopucCheckedCount = 0;
                node.children && node.children.forEach(subNode => {
                    if(subNode.topicType == 'device'){
                        if(subNode.checked){
                            childDeviceTopucCheckedCount ++;
                        }
                        childDeviceTopicTotalCount ++;
                    }
                })
                if(node.checked){
                    if(childDeviceTopicTotalCount && childDeviceTopicTotalCount !== childDeviceTopucCheckedCount){
                        node.checked = false;
                    }
                }
                // if (node.children && node.children.filter(subNode => subNode.topicType == 'device').length) {
                //     if (
                //         node.children.filter(subNode => subNode.topicType == 'device').length !==
                //         node.children.filter(subNode => subNode.topicType == 'device' && subNode.checked).length
                //     ) {
                //         node.checked = false;
                //     }
                // }
            }
        })
        const newTopicList = tree2List(newTopicTree);
        const _newTopicList = deepCloneV2(newTopicList);
        let _tempComDocInstance = comDocInstance;
        // setTopicList(deepCloneV2(_newTopicList))
        _tempComDocInstance.topicList = _newTopicList;
        handleUpdateComDocInstance({..._tempComDocInstance});
    }

    const handleUpdateComDocInstance = (newComDocInstance: DocInstance) => {
        let _newComDocInstance = processDocInstanceBeforeUpdate(newComDocInstance);
        _newComDocInstance.updateComponentName = 'TopicSettingPopover';
        _newComDocInstance.topicList = newComDocInstance.topicList.map(topic => {
            delete topic.children;
            return topic;
        })
        setDelayUpdateComDocInstance({ ..._newComDocInstance });
    }

    return (
        <div style={{ width: '100%', height: '100%' }}>
            <div className="flex-row topic-manage-page-container">
                <div className='flex-col topic-manage-page-content'>
                    <div className='flex-row topic-manage-page-panel-row'>
                        {/*  */}
                        <div className='flex-col topic-manage-page-pannel'>
                            <div className='flex-row topic-manage-page-pannel-title'>
                                <div className='flex-row'>
                                    <div className='topic-manage-page-pannel-step'>1</div>
                                    <div className='topic-manage-page-pannel-title-text'>规划大纲编制</div>
                                </div>
                                <div className='flex-row'>
                                    <Tooltip title={"上一步"}>
                                        <Button type={'text'}><UndoOutlined /></Button>
                                    </Tooltip>
                                    <Tooltip title={"下一步"}>
                                        <Button type={'text'}><RedoOutlined /></Button>
                                    </Tooltip>
                                    <Tooltip title={"展开所有级别大纲"}>
                                        <Button
                                            type={'text'}
                                            onClick={expandAllNode}
                                        >
                                            <ExpandAltOutlined style={{ transform: `rotateZ(-45deg)` }} />
                                        </Button>
                                    </Tooltip>
                                    <Tooltip title={"收起所有级别大纲"}>
                                        <Button
                                            type={'text'}
                                            onClick={unExpandAllNode}
                                        >
                                            <VerticalAlignMiddleOutlined />
                                        </Button>
                                    </Tooltip>
                                </div>
                            </div>
                            <div className='topic-manage-page-pannel-body'>
                                <Search
                                    placeholder='搜索规划大纲'
                                    style={{ marginBottom: 10 }}
                                    value={pureTextTopicTreeDataSearchValue}
                                    onChange={onPureTextTopicTreeDataSearchValueChange}
                                    allowClear
                                    maxLength={10}
                                />
                                <Tree
                                    ref={pureTextTopicTreeRef}
                                    style={{ width: '100%', overflow: 'hidden' }}
                                    showLine
                                    autoExpandParent={false}
                                    defaultExpandAll={false}
                                    switcherIcon={<DownOutlined />}
                                    checkable={true}
                                    //@ts-ignore
                                    titleRender={renderPureTextTopicTreeNode}
                                    expandedKeys={pureTextTopicTreeExpandedKeys}
                                    onExpand={onpureTextTopicTreeExpanded}
                                    //@ts-ignore
                                    treeData={isEmpty(pureTextTopicTreeDataSearchValue) ? pureTextTopicTreeData : filteredForPureTextTopicTree}
                                    selectedKeys={pureTextTopicTreeSelectedNode ? [pureTextTopicTreeSelectedNode.id] : []}
                                    onSelect={onSelectPureTextTopicNode}
                                    checkedKeys={pureTextTreeDataCheckedKeyList}
                                    onCheck={onPureTextTreeDataCheckedChange}
                                    height={windowFullHeight - 250}
                                    blockNode
                                    draggable={{
                                        icon: false,
                                        nodeDraggable: () => isEmpty(pureTextTopicTreeDataSearchValue),
                                    }}
                                    onDragStart={onDragStart}
                                    onDragOver={onDragOver}
                                    onDragEnd={onDragEnd}
                                    onDrop={onTopicNodeDrop}
                                />
                            </div>
                        </div>
                        <div>
                        </div>
                        <div className='flex-col topic-manage-page-pannel' style={{ borderRight: 'none' }}>
                            <div className='flex-row topic-manage-page-pannel-title' style={{ justifyContent: 'space-between' }}>
                                <div className='flex-row'>
                                    <div className='topic-manage-page-pannel-step'>2</div>
                                    <div className='topic-manage-page-pannel-title-text'>规划内容选择</div>
                                </div>
                                <div className='flex-row'>
                                    <div style={{ fontSize: 14 }}>排序方式：</div>
                                    <Select
                                        size={'small'}
                                        style={{ marginRight: 12 }}
                                        value={deviceListSortType}
                                        onChange={onDeviceListSortTypeChange}
                                        options={[
                                            {
                                                value: 'default',
                                                label: '默认排序'
                                            },
                                            {
                                                value: 'checked',
                                                label: '选中优先'
                                            },
                                        ]}
                                    />
                                    <Tooltip
                                        title={"全选/反选面板中显示的规划项目"}
                                    >
                                        <Button
                                            type={checkIsSelectedAllDeviceToicList() ? 'primary' : 'default'}
                                            size={'small'}
                                            style={{ marginRight: 12 }}
                                            disabled={isEmpty(pureTextTopicTreeSelectedNode)}
                                            onClick={switchCheckAllStatus}
                                        >
                                            <CheckOutlined />全选项目
                                        </Button>
                                    </Tooltip>
                                    <Tooltip
                                        title={"添加左侧选中大纲的规划项目"}
                                    >
                                        <Button
                                            type={'primary'}
                                            size={'small'}
                                            disabled={isEmpty(pureTextTopicTreeSelectedNode)}
                                            onClick={handleOpenAddDeviceTopicModal}
                                        >
                                            <PlusCircleOutlined />新建项目
                                        </Button>
                                    </Tooltip>
                                </div>
                            </div>
                            {
                                pureTextTopicTreeSelectedNode && pureTextTopicTreeSelectedNode.id ?
                                    <div className='flex-col topic-manage-page-pannel-body'>
                                        <Search
                                            placeholder='搜索规划内容'
                                            style={{ marginBottom: 10 }}
                                            value={deviceTopicSearchValue}
                                            onChange={onDeviceTopicSearchValueChange}
                                            allowClear
                                            maxLength={10}
                                        />
                                        {
                                            deviceNodeList.length ?
                                                <div className='topic-manage-page-pannel-body-devicelist'>
                                                    {
                                                        deviceNodeList.map(node => {
                                                            return (
                                                                <div
                                                                    className='flex-row device-tree-node'
                                                                    key={node.id}
                                                                    title={node.title}
                                                                    onClick={() => clickDeviceNode(node)}
                                                                >
                                                                    <div className='flex-row device-tree-node-content'>
                                                                        <Checkbox
                                                                            checked={checkDeviceNodeIsChecked(node)}
                                                                            onChange={e => onCheckedChange(e, node)}
                                                                            disabled={checkDeviceNodeIsDisable(node)}
                                                                        />
                                                                        <div style={{ marginLeft: 3, marginRight: 3, opacity: checkDeviceNodeIsDisable(node) ? 0.52 : 1 }}>
                                                                        </div>
                                                                        <div className='single-line-text' style={{ width: 420, fontWeight: node.topicType == 'text' ? 'normal' : 'bold', opacity: checkDeviceNodeIsDisable(node) ? 0.52 : 1 }}>
                                                                            {
                                                                                node.parentTextTopicTitle ?
                                                                                    <span style={{ opacity: 0.52 }}>
                                                                                        [{formatDeviceTopicSearchText(node.parentTextTopicTitle)}]
                                                                                        {" > "}
                                                                                    </span>
                                                                                    :
                                                                                    null
                                                                            }
                                                                            {formatDeviceTopicSearchText(node.title)}
                                                                        </div>
                                                                    </div>
                                                                </div>
                                                            )
                                                        })
                                                    }
                                                </div>
                                                :
                                                <div className='flex-col' style={{ height: '100%', justifyContent: 'center' }}>
                                                    <Empty
                                                        description={`[${pureTextTopicTreeSelectedNode && pureTextTopicTreeSelectedNode.title}]大纲下没有规划项目`}
                                                    />
                                                </div>
                                        }
                                    </div>
                                    :
                                    <div className='flex-col topic-manage-page-pannel-body' style={{ justifyContent: 'center' }}>
                                        <Empty description={"请先点击左侧大纲节点, 选择大纲后即可开始选择规划内容"} />
                                    </div>
                            }
                        </div>
                    </div>
                    <div className='flex-row topic-manage-page-bottom'>
                        <Button
                            style={{ marginRight: 12 }}
                            icon={<UndoOutlined />}
                            onClick={resetTopicListCheckedStatus}
                        >
                            恢复默认推荐
                        </Button>
                        <Button
                            type={'primary'}
                            onClick={confirmToUpdateTopicList}
                        >
                            确认完成
                        </Button>
                    </div>
                </div>
            </div>
            <TopicTreeContextMenu
                ref={contextMenuRef}
                currentScreen={'allTopic'}
                onContextMenuClose={onContextMenuClose}
                currentTopicNode={pureTextTopicTreeSelectedNode}
                onPickerActionType={onPickerTreeNodeActionType}
                allowOption={'just-text'}
            />
            <AddTopicMoal
                ref={addTopicModalRef}
                currentTopicNode={pureTextTopicTreeSelectedNode}
                currentTreeNodeActionType={currentTreeNodeActionType}
                onFinish={onChangeTopic}
            />
            <ReNameTopicModal
                ref={renameTopicModalRef}
                onFinish={_onReNameFinish}
            />
            {contextHolder}
        </div>
    )
}

export default TopicManagePage;